/**
* Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the Eclipse Public License (EPL).
* Please see the license.txt included with this distribution for details.
* Any modifications to this file must keep this entire header intact.
*/
/*
* Created on Feb 11, 2006
*/
package org.python.pydev.parser.prettyprinterv2;
import java.io.IOException;
import org.python.pydev.core.docutils.StringUtils;
import org.python.pydev.core.log.Log;
import com.aptana.shared_core.string.FastStringBuffer;
/**
* Helper to write things in the document marking the last thing written, indent, etc.
*
*/
public class WriteStateV2 implements IWriterEraser {
private IWriterEraser writer;
private IPrettyPrinterPrefs prefs;
private FastStringBuffer indentation = new FastStringBuffer(40);
private boolean nextMustBeNewLineOrComment = false;
private boolean nextMustBeNewLine = true;
public final static int INITIAL_STATE = -1;
public final static int LAST_STATE_NEW_LINE = 0;
public final static int LAST_STATE_INDENT = 1;
public final static int LAST_STATE_WRITE = 2;
private int lastWrite = 0;
int lastState = INITIAL_STATE;
public WriteStateV2(IWriterEraser writer, IPrettyPrinterPrefs prefs) {
this.writer = writer;
this.prefs = prefs;
}
public String getIndentString() {
return indentation.toString();
}
public int getIndentLen() {
return indentation.length();
}
public String getIndentChars(int numberOfChars) {
return indentation.toString().substring(indentation.length() - numberOfChars);
}
public void indent() {
indentation.append(prefs.getIndent());
}
public void dedent() {
int len = indentation.length();
int indentLen = prefs.getIndent().length();
try {
indentation.delete(len - indentLen, len);
} catch (Exception e) {
Log.log(e);
}
eraseIndent();
}
public void eraseIndent() {
if (indentation.length() > 0) {
writer.erase(prefs.getIndent());
}
}
//Writing
public void writeIndent() throws IOException {
lastState = LAST_STATE_INDENT;
writer.write(indentation.toString());
lastWrite++;
}
public void writeNewLine() throws IOException {
writeNewLine(true);
}
public boolean writeNewLine(boolean force) throws IOException {
if (force || lastState == LAST_STATE_WRITE) {
FastStringBuffer buffer = writer.getBuffer();
if (buffer.endsWith(": ")) {
buffer.deleteLast();
}
if (lastState == LAST_STATE_NEW_LINE) {
this.writeIndent();
}
this.nextMustBeNewLineOrComment = false;
this.nextMustBeNewLine = false;
lastState = LAST_STATE_NEW_LINE;
writer.write(prefs.getNewLine());
lastWrite++;
return true;
}
return false;
}
/**
* Writes something, but indents if the last thing written was a new line.
*/
public void write(String o) throws IOException {
if ((nextMustBeNewLineOrComment || nextMustBeNewLine) && this.getBuffer().length() > 0
&& lastState != LAST_STATE_NEW_LINE && lastState != LAST_STATE_INDENT) {
if (nextMustBeNewLine) {
this.writeNewLine();
} else if (nextMustBeNewLineOrComment && !o.trim().startsWith("#")) {
this.writeNewLine();
}
}
nextMustBeNewLineOrComment = false;
nextMustBeNewLine = false;
if (lastState == LAST_STATE_NEW_LINE) {
this.writeIndent();
}
FastStringBuffer buf = this.getBuffer();
if (buf.endsWith("\r") || buf.endsWith("\n") || buf.endsWith(" ") || buf.endsWith("\t")) {
writeRaw(StringUtils.leftTrim(o));
} else {
writeRaw(o);
}
}
/**
* Writes something as it comes (independent on the state)
*/
public void writeRaw(String o) throws IOException {
lastState = LAST_STATE_WRITE;
writer.write(o);
lastWrite++;
}
public void writeWithoutChangingState(String string) throws IOException {
writer.write(string);
lastWrite++;
}
public void writeSpacesBeforeComment() throws IOException {
if (lastState == LAST_STATE_WRITE) {
if (!this.writer.endsWithSpace()) {
writeRaw(prefs.getSpacesBeforeComment());
}
}
}
// Erase
public void erase(String o) {
writer.erase(o);
}
// Temp buffer
public void pushTempBuffer() {
writer.pushTempBuffer();
}
public String popTempBuffer() {
return writer.popTempBuffer();
}
// State
public boolean lastIsWrite() {
return lastState == LAST_STATE_WRITE;
}
public boolean lastIsIndent() {
return lastState == LAST_STATE_INDENT;
}
public boolean lastIsNewLine() {
return lastState == LAST_STATE_NEW_LINE;
}
@Override
public String toString() {
return writer.toString();
}
public int getLastWrite() {
return lastWrite;
}
public void requireNextNewLineOrComment() {
this.nextMustBeNewLineOrComment = true;
}
public void requireNextNewLine() {
this.nextMustBeNewLine = true;
}
public boolean endsWithSpace() {
return this.writer.endsWithSpace();
}
public FastStringBuffer getBuffer() {
return writer.getBuffer();
}
}